package example

import grails.config.Config
import grails.test.hibernate.HibernateSpec
import org.grails.config.PropertySourcesConfig
import org.grails.datastore.mapping.config.Settings
import org.grails.datastore.mapping.multitenancy.resolvers.SystemPropertyTenantResolver
import org.grails.orm.hibernate.HibernateDatastore
import org.springframework.boot.env.PropertySourceLoader
import org.springframework.core.env.PropertyResolver
import org.springframework.core.env.PropertySource
import org.springframework.core.io.DefaultResourceLoader
import org.springframework.core.io.ResourceLoader
import org.springframework.core.io.support.SpringFactoriesLoader

abstract class HibernateFixedTenantContextSpec extends HibernateSpec {
    void setupSpec() {

        List<PropertySourceLoader> propertySourceLoaders = SpringFactoriesLoader.loadFactories(PropertySourceLoader.class, getClass().getClassLoader())
        ResourceLoader resourceLoader = new DefaultResourceLoader()

        List<PropertySource> propertySources = []

        PropertySourceLoader ymlLoader = propertySourceLoaders.find { it.getFileExtensions().toList().contains("yml") }
        if (ymlLoader) {
            propertySources.addAll(load(resourceLoader, ymlLoader, "application.yml"))
        }
        PropertySourceLoader groovyLoader = propertySourceLoaders.find { it.getFileExtensions().toList().contains("groovy") }
        if (groovyLoader) {
            propertySources.addAll(load(resourceLoader, groovyLoader, "application.groovy"))
        }

        Map<String, Object> mapPropertySource = getConfiguration() as Map<String, Object>
        def map1 = propertySources
                .findAll { it.getSource() }
                .collectEntries { it.getSource() as Map }

        map1 += mapPropertySource

        Config config = new PropertySourcesConfig(map1)
        List<Class> domainClasses = getDomainClasses()
        String packageName = getPackageToScan(config)

        if (!domainClasses) {
            Package packageToScan = Package.getPackage(packageName) ?: getClass().getPackage()
            $spock_sharedField_hibernateDatastore = new HibernateDatastore((PropertyResolver) config, packageToScan)
        } else {
            $spock_sharedField_hibernateDatastore = new HibernateDatastore((PropertyResolver) config, domainClasses as Class[])
        }
        $spock_sharedField_transactionManager = $spock_sharedField_hibernateDatastore.getTransactionManager()
    }

    @Override
    Map getConfiguration() {
        [(Settings.SETTING_MULTI_TENANT_RESOLVER_CLASS): SystemPropertyTenantResolver]
    }

    def setup() {
        System.setProperty(SystemPropertyTenantResolver.PROPERTY_NAME, 'audi')
    }

    def cleanup() {
        System.setProperty(SystemPropertyTenantResolver.PROPERTY_NAME, '')
    }
}
